class MyEvent {
  list: { [key: string]: any[] } = {};

  on(eventName: string, fn) {
    if (!this.list[eventName]) {
      this.list[eventName] = [];
    }
    this.list[eventName].push(fn);
  }

  emit(eventName: string, ...args) {
    const events = this.list[eventName] || [];
    events.forEach((fn) => {
      fn(...args);
    });
  }

  once(eventName: string, fn) {
    const hook = (...args) => {
      fn(...args);
      this.off(eventName, hook);
    };
    this.on(eventName, hook);
  }

  off(eventName: string, fn?) {
    const events = this.list[eventName];
    if (Array.isArray(events)) {
      this.list[eventName] = fn ? events.filter((i) => i !== fn) : [];
    }
  }
}

export default MyEvent;
